package services

import (
	"bbs-go/internal/consts"
	"bbs-go/internal/models/constants"

	"github.com/mlogclub/simple/sqls"
	"github.com/mlogclub/simple/web/params"
	"gorm.io/gorm"

	"bbs-go/internal/models"
	"bbs-go/internal/repositories"
)

var ChatGroupsService = newChatGroupsService()

func newChatGroupsService() *chatGroupsService {
	return &chatGroupsService{}
}

type chatGroupsService struct {
}

func (s *chatGroupsService) Get(id int64) *models.ChatGroups {
	return repositories.ChatGroupsRepository.Get(sqls.DB(), id)
}

func (s *chatGroupsService) Take(where ...interface{}) *models.ChatGroups {
	return repositories.ChatGroupsRepository.Take(sqls.DB(), where...)
}

func (s *chatGroupsService) Find(cnd *sqls.Cnd) []models.ChatGroups {
	return repositories.ChatGroupsRepository.Find(sqls.DB(), cnd)
}

func (s *chatGroupsService) FindPageByParams(params *params.QueryParams) (list []models.ChatGroups, paging *sqls.Paging) {
	return repositories.ChatGroupsRepository.FindPageByParams(sqls.DB(), params)
}

func (s *chatGroupsService) FindPageByCnd(cnd *sqls.Cnd) (list []models.ChatGroups, paging *sqls.Paging) {
	return repositories.ChatGroupsRepository.FindPageByCnd(sqls.DB(), cnd)
}

func (s *chatGroupsService) Create(t *models.ChatGroups) error {
	return repositories.ChatGroupsRepository.Create(sqls.DB(), t)
}

func (s *chatGroupsService) Update(t *models.ChatGroups) error {
	return repositories.ChatGroupsRepository.Update(sqls.DB(), t)
}

func (s *chatGroupsService) Updates(id int64, columns map[string]interface{}) error {
	return repositories.ChatGroupsRepository.Updates(sqls.DB(), id, columns)
}

func (s *chatGroupsService) UpdateColumn(id int64, name string, value interface{}) error {
	return repositories.ChatGroupsRepository.UpdateColumn(sqls.DB(), id, name, value)
}

func (s *chatGroupsService) DeleteByArticleId(articleId int64) {
	sqls.DB().Model(models.ChatGroups{}).Where("article_id = ?", articleId).UpdateColumn("status", constants.StatusDeleted)
}

func (s *chatGroupsService) CreateGroup(t *models.ChatGroups) error {
	tx := sqls.DB().Begin()
	err := tx.Model(&models.ChatGroups{}).Create(t).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Model(&models.ChatGroupsMembers{}).Create(&models.ChatGroupsMembers{
		GroupId:   t.Id,
		GroupName: t.Name,
		UserId:    t.CreatedId,
		RoleId:    consts.ChatGroupsMembersRoleId_3,
	}).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Model(&models.ChatGroupsMembersUnreadMessage{
		GroupId: t.Id,
		UserId:  t.CreatedId,
		UnRead:  false,
	}).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

func (s *chatGroupsService) UpdateGroupBaseInfo(t *models.ChatGroups) error {
	err := sqls.DB().Model(&models.ChatGroups{}).Where("id = ?", t.Id).UpdateColumns(map[string]interface{}{
		"name":      t.Name,
		"avatar":    t.Avatar,
		"introduce": t.Introduce,
	}).Error
	if err != nil {
		return err
	}

	return nil
}

func (s *chatGroupsService) UpdateGroupAvatar(groupId int64, avatar string) error {
	err := sqls.DB().Model(&models.ChatGroups{}).Where("id = ?", groupId).UpdateColumns(map[string]interface{}{
		"avatar": avatar,
	}).Error
	if err != nil {
		return err
	}

	return nil
}

func (s *chatGroupsService) FindByGroupName(groupName string) (models.ChatGroups, error) {
	chatGroups := models.ChatGroups{}
	err := sqls.DB().Model(models.ChatGroups{}).Where("name = ?", groupName).First(&chatGroups).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatGroups{}, err
	}
	return chatGroups, nil
}

func (s *chatGroupsService) FindByGroupId(groupId int64) (models.ChatGroups, error) {
	chatGroups := models.ChatGroups{}
	err := sqls.DB().Model(models.ChatGroups{}).Where("id = ?", groupId).First(&chatGroups).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatGroups{}, err
	}
	return chatGroups, nil
}

func (s *chatGroupsService) DissolveGroup(groupId int64) error {
	tx := sqls.DB().Begin()
	group := models.ChatGroups{}
	err := tx.Model(&models.ChatGroups{}).Where("id = ?", groupId).First(&group).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Delete(&models.ChatGroups{}, "id = ?", groupId).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Delete(&models.ChatGroupsMembers{}, "group_id = ?", groupId).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

func (s *chatGroupsService) FindMyChatGroupsList(userId int64) ([]models.ChatGroupsMembers, error) {
	chatGroupsMembers := []models.ChatGroupsMembers{}
	err := sqls.DB().Model(&models.ChatGroupsMembers{}).Where("user_id = ?", userId).Find(&chatGroupsMembers).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return chatGroupsMembers, nil
}
